#include "messageeditarea.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QScrollBar>
#include <QFileDialog>

#include "historymessagewidget.h"
#include "model/datacenter.h"
#include "mainwidget.h"
#include "toast.h"
#include "soundrecorder.h"

using namespace model;

MessageEditArea::MessageEditArea(QWidget *parent)
    : QWidget{parent}
{
    // 设置基础属性
    this->setFixedHeight(180);
    this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    //创建垂直布局管理器
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setContentsMargins(10,0,10,10);
    vlayout->setSpacing(0);
    this->setLayout(vlayout);

    //创建水平方向的布局管理器
    QHBoxLayout* hlayout = new QHBoxLayout();
    hlayout->setContentsMargins(10,0,0,0);
    hlayout->setSpacing(0);
    hlayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    vlayout->addLayout(hlayout);

    //将四个按钮添加到水平布局管理器中
    QString btnStyle = "QPushButton { background-color: transparent; border: none; } QPushButton:pressed { background-color: rgb(200, 200, 200); }";
    QSize btnSize(35,35); // 按钮大小
    QSize iconSize(25,25); // 图片大小

    sendImageBtn = new QPushButton();
    sendImageBtn->setFixedSize(btnSize);
    sendImageBtn->setIconSize(iconSize);
    sendImageBtn->setIcon(QIcon(":/resource/image/image.png"));
    sendImageBtn->setStyleSheet(btnStyle);
    hlayout->addWidget(sendImageBtn);

    sendFileBtn = new QPushButton();
    sendFileBtn->setFixedSize(btnSize);
    sendFileBtn->setIconSize(iconSize);
    sendFileBtn->setIcon(QIcon(":/resource/image/file.png"));
    sendFileBtn->setStyleSheet(btnStyle);
    hlayout->addWidget(sendFileBtn);

    sendSpeechBtn  = new QPushButton();
    sendSpeechBtn ->setFixedSize(btnSize);
    sendSpeechBtn ->setIconSize(iconSize);
    sendSpeechBtn ->setIcon(QIcon(":/resource/image/sound.png"));
    sendSpeechBtn ->setStyleSheet(btnStyle);
    hlayout->addWidget(sendSpeechBtn);

    showHistoryBtn = new QPushButton();
    showHistoryBtn->setFixedSize(btnSize);
    showHistoryBtn->setIconSize(iconSize);
    showHistoryBtn->setIcon(QIcon(":/resource/image/history.png"));
    showHistoryBtn->setStyleSheet(btnStyle);
    hlayout->addWidget(showHistoryBtn);

    //添加多行编辑器
    textEdit = new QPlainTextEdit();
    textEdit->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    textEdit->setStyleSheet("QPlainTextEdit { border: none; background-color: transparent; font-size: 14px; padding: 10px; }");
    textEdit->verticalScrollBar()->setStyleSheet("QSsrollBar:vertical { width: 2px; background-color: gdb(45,45,45); }");
    vlayout->addWidget(textEdit);

    // 添加录制中的Label
    tipLabel = new QLabel();
    tipLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    tipLabel->setText("录音中...");
    tipLabel->setAlignment(Qt::AlignCenter);
    tipLabel->setFont(QFont("微软雅黑", 24, 600));
    vlayout->addWidget(tipLabel);
    tipLabel->hide();

    //添加发送按钮
    sendTextBtn  = new QPushButton();
    sendTextBtn->setText("发送");
    sendTextBtn->setFixedSize(120,40);
    QString style = "QPushButton { font-size: 16px; color: rgb(7, 193, 96); border: none; background-color: rgb(233, 233, 233); border-radius: 10px; } ";
    style += "QPushButton:hover { background-color: rgb(210, 210, 210); }";
    style += "QPushButton:pressed { background-color: rgb(190, 190, 190); }";
    sendTextBtn->setStyleSheet(style);
    vlayout->addWidget(sendTextBtn,0,Qt::AlignRight | Qt::AlignVCenter);


    //初始化信号槽
    initSignalSlot();
}

void MessageEditArea::initSignalSlot()
{
    DataCenter* dataCenter = DataCenter::getInstance();

    //连接信号槽，处理点击历史信息的按钮
    connect(showHistoryBtn,&QPushButton::clicked,this,[=](){
        if (dataCenter->getCurrentChatSessionId().isEmpty()) {
            return;
        }
        HistoryMessageWidget* historyMessageWidget = new HistoryMessageWidget(this);
        historyMessageWidget->exec();
    });

    // 关联发送文本消息按钮
    connect(sendTextBtn, &QPushButton::clicked,this,&MessageEditArea::sendTextMessage);
    connect(dataCenter, &DataCenter::sendMessageDone, this, &MessageEditArea::addSelfMessage);

    // 关联收到消息
    connect(dataCenter,&DataCenter::receiveMessageDone,this,&MessageEditArea::addOtherMessage);

    // 关联发送图片消息
    connect(sendImageBtn,&QPushButton::clicked,this,&MessageEditArea::clickSendImageBtn);

    // 5. 关联 "发送文件" 信号槽
    connect(sendFileBtn, &QPushButton::clicked, this, &MessageEditArea::clickSendFileBtn);

    // 发送语音消息
    connect(sendSpeechBtn, &QPushButton::pressed, this, &MessageEditArea::speechRecordPressed);
    connect(sendSpeechBtn, &QPushButton::released, this, &MessageEditArea::speechRecordReleased);
    SoundRecorder* soundRecorder = SoundRecorder::getInstance();
    connect(soundRecorder, &SoundRecorder::soundRecordDone, this, &MessageEditArea::sendSpeech);
}

void MessageEditArea::sendTextMessage()
{
    // 判断会话是否被选中
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        LOG() << "当前未选中任何会话, 不会发送消息!";
        Toast::showMessage("当前未选中会话, 不发送任何消息!");
        return;
    }

    // 获取到会话内容
    const QString& content = textEdit->toPlainText().trimmed();
    if(content.isEmpty()) {
        LOG() << "输入框为空";
        return;
    }

    //清空输入框已有的内容
    textEdit->clear();

    // 将内容发送给服务器
    dataCenter->sendTextMessageAsync(dataCenter->getCurrentChatSessionId(),content);
}

// 将自己发送的消息显示到界面上
void MessageEditArea::addSelfMessage(MessageType messageType, const QByteArray &content, const QString &extraInfo)
{
    DataCenter* dataCenter = DataCenter::getInstance();
    const QString& currentChatSessionId = dataCenter->getCurrentChatSessionId();

    // 构造消息，然后将消息插入到消息列表中
    Message message = Message::createMessage(messageType,currentChatSessionId,*dataCenter->getMyself(),content,extraInfo);
    dataCenter->addMessage(message);

    // 将消息展示区中添加消息
    MainWidget* mainWidget = MainWidget::getInstance();
    MessageShowArea* messageShowArea = mainWidget->getMessageShowArea();

    messageShowArea->addMessage(false,message);

    // 控制消息显示区, 滚动条, 滚动到末尾.
    messageShowArea->scrollToEndLater();

    // 通知一下，已经将消息插入到界面中，要更新最新的一条消息
    emit dataCenter->updateLastMessage(currentChatSessionId);
}

void MessageEditArea::addOtherMessage(const Message &message)
{
    DataCenter* dataCenter = DataCenter::getInstance();
    // 获取到消息展示区
    MainWidget* mainWidget = MainWidget::getInstance();
    MessageShowArea* messageShowArea = mainWidget->getMessageShowArea();

    messageShowArea->addMessage(true,message);

    // 控制消息显示区, 滚动条, 滚动到末尾.
    messageShowArea->scrollToEndLater();

    // 发送信号, 通知会话列表, 更新最后一条消息
    emit dataCenter->updateLastMessage(message.chatSessionId);
}

void MessageEditArea::clickSendImageBtn()
{
    // 判断会话是否被选中
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        Toast::showMessage("当前未选中会话, 不能进行点击!");
        return;
    }

    QString filter = "Image Files (*.png *.jpg *.jpeg)";
    QString imagePath = QFileDialog::getOpenFileName(this, "选择图片", QDir::homePath(), filter);
    if (imagePath.isEmpty()) {
        LOG() << "用户取消选择图片";
        return;
    }

    // 读取文件内容
    QByteArray imageContent = loadFileToQByteArray(imagePath);
    dataCenter->sendImageMessageAsync(dataCenter->getCurrentChatSessionId(), imageContent);
}

void MessageEditArea::clickSendFileBtn()
{
    // 判断会话是否被选中
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        Toast::showMessage("当前未选中会话, 不能进行点击!");
        return;
    }

    // 2. 弹出对话框, 选择文件.
    QString filter = "*";
    QString path = QFileDialog::getOpenFileName(this, "选择文件", QDir::homePath(), filter);
    if (path.isEmpty()) {
        // 如果用户弹框之后, 没有真正选择文件, 而是取消了. 返回值就是 ""
        LOG() << "用户取消选择文件";
        return;
    }

    QByteArray content = loadFileToQByteArray(path);

    QFileInfo fileInfo(path);
    const QString& fileName = fileInfo.fileName();

    dataCenter->sendFileMessageAsync(dataCenter->getCurrentChatSessionId(), fileName, content);
}

void MessageEditArea::speechRecordPressed()
{
    // 判断会话是否被选中
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        Toast::showMessage("当前未选中会话, 不能进行点击!");
        return;
    }

    sendSpeechBtn->setIcon(QIcon(":/resource/image/sound_active.png"));

    // 开始录音
    SoundRecorder* soundRecorder = SoundRecorder::getInstance();
    soundRecorder->startRecord();

    tipLabel->show();
    textEdit->hide();
}

void MessageEditArea::speechRecordReleased()
{
    // 判断会话是否被选中
    DataCenter* dataCenter = DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        Toast::showMessage("当前未选中会话, 不能进行点击!");
        return;
    }

    sendSpeechBtn ->setIcon(QIcon(":/resource/image/sound.png"));

    SoundRecorder* soundRecorder = SoundRecorder::getInstance();
    soundRecorder->stopRecord();

    tipLabel->hide();
    textEdit->hide();
}


void MessageEditArea::sendSpeech(const QString &path)
{
    DataCenter* dataCenter = DataCenter::getInstance();
    // 获取语音文件的内容
    QByteArray speechContent = loadFileToQByteArray(path);
    if (speechContent.isEmpty()) {
        LOG() << "语音文件加载失败";
        return;
    }

    dataCenter->sendSpeechMessageAsync(dataCenter->getCurrentChatSessionId(),speechContent);
}


